//
// Created by denglibin on 2019/6/17 0017.
//

/**
C++98 auto
早在C++98标准中就存在了auto关键字，那时的auto用于声明变量为自动变量，自动变量意为拥有自动的生命期，这是多余的，
 因为就算不使用auto声明，变量依旧拥有自动的生命期：

int a =10 ;  //拥有自动生命期
auto int b = 20 ;//拥有自动生命期
static int c = 30 ;//延长了生命期
C++98中的auto多余且极少使用，C++11已经删除了这一用法，取而代之的是全新的auto：变量的自动类型推断。

C++11 auto
auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型，类似的关键字还有decltype。
*/
#include <iostream>
#include <vector>
using namespace std;

template <typename _Tx,typename _Ty>

//在定义模板函数时，用于声明依赖模板参数的变量类型
void Multiply(_Tx x, _Ty y) {
    auto v = x*y;
    //若不使用auto变量来声明v，那这个函数就难定义啦，不到编译的时候，谁知道x*y的真正类型是什么呢
    std::cout << v;
}

//模板函数依赖于模板参数的返回值

//当模板函数的返回值依赖于模板的参数时，我们依旧无法在编译代码前确定模板参数的类型，故也无从知道返回值的类型，这时我们可以使用auto
//decltype操作符用于查询表达式的数据类型，也是C++11标准引入的新的运算符，其目的也是解决泛型编程中有些类型由模板参数决定，而难以表示它的问题。
//auto在这里的作用也称为返回值占位，它只是为函数返回值占了一个位置，真正的返回值是后面的decltype(_Tx*_Ty)
template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y) {
    return x*y;
}

int main49(){
    int a = 10;
    auto au_a = a;//自动类型推导 au_a为int类型
    cout << typeid(au_a).name() << endl;
    vector<int > v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    for(vector<int>::iterator i = v.begin(); i != v.end(); i++){
        cout << *i << endl;
    }
    //使用auto
    for(auto i = v.begin(); i != v.end(); i++){
        cout << *i  << endl;
    }
    cout << multiply(1, 4) << endl;

    return 0;
}